package com.lingdian.fund.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import okhttp3.OkHttpClient;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.lingdian.common.util.HttpUtil;
import com.lingdian.fund.bean.Fund;
import com.lingdian.fund.bean.FundData;
import com.lingdian.fund.repository.FundDataReporsitory;
import com.lingdian.fund.repository.FundRepository;
import com.lingdian.fund.service.SpiderDataService;
@Component("spiderDataService")
@Scope("prototype")
public class SpiderDataServiceImpl implements SpiderDataService{
	@Autowired
	private FundDataReporsitory fundDataReporsitory;
	@Autowired
	private FundRepository fundRepository;
	
	@PersistenceContext
	private EntityManager entityManager;
/*	
	private List<Fund> funddataList;
	private String enddate;*/
	
/*
	public SpiderDataServiceImpl(List<Fund> funddataList, String enddate) {
		super();
		this.funddataList = funddataList;
		this.enddate = enddate;
	}
*/
	@Override
	public String spiderHtml(String code,String startDate,String endDate) {
		String _url = "http://fund.fund123.cn/HistoryNV/NetValueHistoryTable.aspx?code="+code+"&startdate="+startDate+"&enddate="+endDate;
		String result = null;
		
		try {
			result = HttpUtil.get(_url, "");
		} catch (Exception e) {
			e.printStackTrace();
			result  = null;
		}
		return result;
	}

	@Override
	public List<FundData> parseData(String html) {
		Document dom = Jsoup.parse(html);
		Elements elements = dom.body().select("#tblContent").select(".tr");
		List<FundData> list = new ArrayList<FundData>();
		for(int i=0;i<elements.size();i++){
			Elements es = elements.get(i).select("td");
			String fundDate = es.get(0).text();
			String unitValue = es.get(1).text();
			String cumulativeValue = es.get(2).text();
			String growthValue = es.get(3).text();
			String growthRate = es.get(4).text();
			FundData data = new FundData();
			data.setCreateAt(new Date());
			data.setFundDate(fundDate);
			data.setUnitValue(Double.parseDouble(unitValue));
			data.setCumulativeValue(Double.valueOf(cumulativeValue));
			data.setGrowthRate(growthRate);
			data.setGrowthValue(Double.valueOf(growthValue));
			list.add(data);
		}
		return list;
	}

	@Override
	public void saveData(FundData data) {
		List<FundData> fundDatas = fundDataReporsitory.findByCodeAndFundDate(data.getCode(), data.getFundDate());
		if(fundDatas.size()==0){
			fundDataReporsitory.save(data);
		}
	}

	@Override
	public void asyncSaveData(List<Fund> _funddataList,String _enddate) {
		

		for(Fund fund :_funddataList){
			System.out.println("index"+fund.getName());
			List<FundData> exists = fundDataReporsitory.findByCodeAndFundDate(fund.getId(), _enddate);
			if(exists.size()==0){
//				System.out.println(Thread.currentThread().getId());
				try {
					String _url = "http://fund.fund123.cn/HistoryNV/NetValueHistoryTable.aspx?code="+fund.getId()+"&startdate=2010-10-13&enddate="+_enddate;
					String html= HttpUtil.get(_url, "");
					List<FundData> list = this.parseData(html);
					for(FundData data:list){
						data.setCode(fund.getId());
						this.saveData(data);
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			}
	
		
	}

	public Map<Integer,List<Fund>> splitFund(){
		Iterator<Fund> iterator = fundRepository.findAllByOrderById().iterator();
		int index = 0;
		int size=20;
		Map<Integer,List<Fund>> listMap = new HashMap<Integer,List<Fund>>();
		while(iterator.hasNext()){
			Fund fund = iterator.next();
			int i  = index/size+1;
			if(listMap.containsKey(i)){
				listMap.get(i).add(fund);
			}else{
				List<Fund> list = new ArrayList<Fund>();
				list.add(fund);
				listMap.put(i, list);
			}
			index++;
		}
		return listMap;
	}
	private class MuilInsert implements Runnable{

		private List<Fund> _funddataList;
		private FundDataReporsitory _fundDataReporsitory;
		private String  _enddate;
		
		public MuilInsert(List<Fund> _funddataList,
				FundDataReporsitory _fundDataReporsitory, String _enddate) {
			super();
			this._funddataList = _funddataList;
			this._fundDataReporsitory = _fundDataReporsitory;
			this._enddate = _enddate;
		}
		public MuilInsert() {
			super();
		}

		@Override
		public void run() {
			System.out.println("多线程:"+Thread.currentThread().getId());
			for(Fund fund :_funddataList){
				System.out.println("_fundDataReporsitory:"+_fundDataReporsitory.getClass());
				List<FundData> exists = _fundDataReporsitory.findByCodeAndFundDate(fund.getId(), _enddate);
				System.out.println("获取exists:"+exists.size());
				if(exists.size()==0){
//					System.out.println(Thread.currentThread().getId());
					try {
						String _url = "http://fund.fund123.cn/HistoryNV/NetValueHistoryTable.aspx?code="+fund.getId()+"&startdate=2010-10-13&enddate="+_enddate;
						String html= HttpUtil.get(_url, "");
						List<FundData> list = this.parseData(html);
						for(FundData data:list){
							data.setCode(fund.getId());
							this.saveData(data);
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				}
		}
		public List<FundData> parseData(String html) {
			Document dom = Jsoup.parse(html);
			Elements elements = dom.body().select("#tblContent").select(".tr");
			List<FundData> list = new ArrayList<FundData>();
			for(int i=0;i<elements.size();i++){
				Elements es = elements.get(i).select("td");
				String fundDate = es.get(0).text();
				String unitValue = es.get(1).text();
				String cumulativeValue = es.get(2).text();
				String growthValue = es.get(3).text();
				String growthRate = es.get(4).text();
				FundData data = new FundData();
				data.setCreateAt(new Date());
				data.setFundDate(fundDate);
				data.setUnitValue(Double.parseDouble(unitValue));
				data.setCumulativeValue(Double.valueOf(cumulativeValue));
				data.setGrowthRate(growthRate);
				data.setGrowthValue(Double.valueOf(growthValue));
				list.add(data);
			}
			return list;
		}
		private void saveData(FundData data) {
//			List<FundData> fundDatas = _fundDataReporsitory.findByCodeAndFundDate(data.getCode(), data.getFundDate());
//			if(fundDatas.size()==0){
				_fundDataReporsitory.save(data);
//			}
		}
	
		
	}
	public MuilInsert getMuilInsert(List<Fund> _funddataList,
			FundDataReporsitory _fundDataReporsitory, String _enddate){
		return new MuilInsert(_funddataList, _fundDataReporsitory, _enddate);
	}
	@Override
	public void threadUpdateAll(){
		try {
			Map<Integer,List<Fund>> listMap = splitFund();
			String enddate ="2017-01-19"; 
			SpiderDataServiceImpl mulThreadService = new SpiderDataServiceImpl();
			int poolCount, totalCount;
			poolCount = 10;// 同时跑的线程数
			ExecutorService pool = Executors.newFixedThreadPool(poolCount);
			for(Integer index:listMap.keySet()){
					SpiderDataServiceImpl.MuilInsert m = mulThreadService.getMuilInsert(listMap.get(index), fundDataReporsitory, enddate);
					Thread t = new Thread(m);
					pool.execute(t);
			}
			pool.shutdown();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public List<Object[]> findByMaxUnitValue(String funDate) {
		String sql = "select maxv,minv,rangedata,b.tvalue,(a.minv-b.tvalue) as tt from "
				+ " ("
				+ " SELECT code,MAX(unitValue) as maxv ,min(unitValue) as minv ,MAX(unitValue)-min(unitValue) as rangedata from fundData where fundDate>='2016-05-19' group by code"
				+ " )a,"
				+ " (SELECT unitValue as tvalue,code from fundData where fundDate='2017-01-19')b"
				+ " where a.code = b.code ORDER BY rangedata desc ,tt ";
		return entityManager.createQuery(sql).getResultList();
//		return fundDataReporsitory.findByMaxUnitValue(funDate);
	}
	public void updateOne(String code, String startDate, String endDate) {
		String html = spiderHtml(code, startDate, endDate);
		List<FundData> list = parseData(html);
		for(FundData fundData:list){
			List<FundData> exist = fundDataReporsitory.findByCodeAndFundDate(code, fundData.getFundDate());
			if(exist.size()==0){
				fundData.setCode(code);
				fundDataReporsitory.save(fundData);
			}
		}
		
	}
	


	 

}
